package com.fit.utils.dev.code.generation.utils;

import com.alibaba.druid.pool.DruidDataSource;
import com.fit.utils.dev.code.generation.model.TablePrimaryModel;
import com.fit.utils.se.IOUtil;
import com.fit.utils.se.VelocityUtil;
import org.apache.velocity.VelocityContext;

import java.io.*;

public class MyBatisGeneratorUtils {


	/**
	 * @description: 生成model
	 * @param: dataSourcePool 连接池
	 * @param: basicPath 项目的绝对路径(精确到: 项目/src/main/java/)
	 * @param: basicPackageName 基础的包名
	 * @param: tablePrimaryModel 表信息
	 * @param:	basicModelClassName	所有model需要继承的java类名
	 * @return: java.lang.String
	 * @author: hcl
	 * @date: created in 2018/1/19 15:30
	 */
	public static String generatorModelCode(
							DruidDataSource dataSourcePool,
							String basicPath,
							String basicPackageName,
							TablePrimaryModel tablePrimaryModel,
							String basicModelClassName){
		basicPath = GeneratorUtils.addPathLine(basicPath);

		String basicModelPackageName = basicPackageName+".basic";

		//根据配置文件生成原始的model
		VelocityContext context = new VelocityContext();
		context.put("basicModelClassName",basicModelClassName);
		context.put("jdbcDriver", dataSourcePool.getDriverClassName());
		context.put("jdbcUrl", dataSourcePool.getUrl());
		context.put("jdbcName", dataSourcePool.getUsername());
		context.put("jdbcPassword", dataSourcePool.getPassword());
		context.put("basicModelPackageName",basicModelPackageName);
		context.put("basicPath", basicPath);
		context.put("tableName", tablePrimaryModel.getTableName());
		context.put("modelName",GeneratorUtils.getModelName(tablePrimaryModel)+"Model");
		context.put("primaryColumnName", tablePrimaryModel.getPrimaryColumnName());
		context.put("autoIncrement", tablePrimaryModel.isAutoIncrement());
		String configTemplate = GeneratorUtils.getTemplate("generatorConfigModel.vm");
		GeneratorUtils.generateByConfig(VelocityUtil.generateTemplateStrInstanceToInput(context, configTemplate));

		//生成扩展的model
		String modelPath = basicPath + basicPackageName.toString().replaceAll("\\.", "/");
		modelPath = GeneratorUtils.addPathLine(modelPath);
		VelocityContext modelContext = new VelocityContext();
		modelContext.put("basicPackageName",basicPackageName);
		modelContext.put("parentModelClassName",basicModelPackageName+"."+context.get("modelName"));
		modelContext.put("parentModelName",context.get("modelName"));
		modelContext.put("tableName",tablePrimaryModel.getTableName());
		modelContext.put("modelName",GeneratorUtils.getModelName(tablePrimaryModel));
		String modelTemplate = GeneratorUtils.getTemplate("Model.vm");
		GeneratorUtils.generator(modelPath, GeneratorUtils.getModelName(tablePrimaryModel) +".java", modelTemplate, modelContext, false);
		return basicPackageName+"."+GeneratorUtils.getModelName(tablePrimaryModel);
	}

	/**
	 * @description: 根据路径生成xml或和model
	 * @param dataSourcePool 连接池
	 * @param basicPath 项目的绝对路径(精确到: 项目/src/main/java/)
	 * @param basicPackageName mapper接口生成的包路径
	 * @param tablePrimaryModel 表信息
	 * @param basicModelClassName 所有model需要继承的java类名
	 * @param modelClassName 对应的model的类名
	 * @param modelClassName xml文件生成的包路径,基于 /src/main/resources/ 路径下的包名
	 * @param basicMapperClassName 所有Mapper需要基础的接口
	 * @param xmlFilePackage mapper.xml需要生成到resources下的路径
	 * @return: void
	 * @author: hcl
	 * @date: created in 2018/1/19 9:16
	 */
	public static void generatorXmlCode(DruidDataSource dataSourcePool,
										String basicPath,
										String basicPackageName,
										TablePrimaryModel tablePrimaryModel,
										String basicModelClassName,
										String modelClassName,
										String basicMapperClassName,
										String xmlFilePackage){
		String resourcesPath = GeneratorUtils.addPathLine(new File(basicPath).getParent()).replaceAll("\\\\", "/")+"resources/";
		basicPath = GeneratorUtils.addPathLine(basicPath);

		String mapperBasicPackageName = basicPackageName+".dao";

		String mapperPath = basicPath + mapperBasicPackageName.replaceAll("\\.", "/");
		mapperPath = GeneratorUtils.addPathLine(mapperPath);

		//生成mapper
		VelocityContext mapperContext = new VelocityContext();
		mapperContext.put("mapperBasicPackageName",mapperBasicPackageName);
		mapperContext.put("modelClassName",modelClassName);
		mapperContext.put("modelName",GeneratorUtils.getSimpleClassName(modelClassName));
		mapperContext.put("basicMapperClassName",basicMapperClassName);
		mapperContext.put("basicMapperName",GeneratorUtils.getSimpleClassName(basicMapperClassName));
		mapperContext.put("mapperModelName",mapperContext.get("modelName")+"Mapper");
		String mapperTemplate = GeneratorUtils.getTemplate("Mapper.vm");
		GeneratorUtils.generator(mapperPath, mapperContext.get("mapperModelName")+".java", mapperTemplate, mapperContext, false);


		//根据配置文件生成原始的xml
		VelocityContext configContext = new VelocityContext();
		configContext.put("basicModelClassName",basicModelClassName);
		configContext.put("jdbcDriver", dataSourcePool.getDriverClassName());
		configContext.put("jdbcUrl", dataSourcePool.getUrl());
		configContext.put("jdbcName", dataSourcePool.getUsername());
		configContext.put("jdbcPassword", dataSourcePool.getPassword());
		configContext.put("xmlFilePackage",xmlFilePackage);
		configContext.put("resourcesPath", resourcesPath);
		configContext.put("tableName", tablePrimaryModel.getTableName());
		configContext.put("primaryColumnName", tablePrimaryModel.getPrimaryColumnName());
		configContext.put("autoIncrement", tablePrimaryModel.isAutoIncrement());
		configContext.put("mapperModelName",mapperContext.get("mapperModelName"));
		String configTemplate = GeneratorUtils.getTemplate("generatorConfigXml.vm");
		GeneratorUtils.generateByConfig(VelocityUtil.generateTemplateStrInstanceToInput(configContext, configTemplate));


		//删除model
		String modelFileDir = resourcesPath + xmlFilePackage.replaceAll("\\.", "/");
		modelFileDir = GeneratorUtils.addPathLine(modelFileDir);
		String modelFilePath = modelFileDir+configContext.get("mapperModelName")+".java";
		File modelFile = new File(modelFilePath);
		if(modelFile.exists()){
			modelFile.delete();
		}



		//覆盖xml BaseResultMap
		configContext.put("mapperClassName", mapperBasicPackageName +"."+ mapperContext.get("mapperModelName"));
		configContext.put("modelClassName",modelClassName);
		String mapperXmlTemplate = GeneratorUtils.getTemplate("Mapper.xml.vm");
		String mapperXmlFileName = configContext.get("mapperModelName").toString()+".xml";
		String saveXmlMapperPath = GeneratorUtils.addPathLine(resourcesPath + xmlFilePackage.replaceAll("\\.", "/"));
		String deleteXmlMapperPath = GeneratorUtils.addPathLine(resourcesPath + xmlFilePackage.replaceAll("\\.", "/")).toString()+configContext.get("mapperModelName").toString()+"Mapper.xml";


		File saveFile = new File(saveXmlMapperPath+mapperXmlFileName);
		File deleteFile = new File(deleteXmlMapperPath);
		if(deleteFile.exists()){
			try {
				String deleteXmlStr = IOUtil.toString(new FileInputStream(deleteFile), "utf-8");

				Integer indexS = deleteXmlStr.indexOf(">",deleteXmlStr.indexOf("<resultMap"));
				String resultMapElements = deleteXmlStr.substring(indexS+1, deleteXmlStr.indexOf("</resultMap>",indexS+1));
				configContext.put("resultMapElements", resultMapElements);
				if(!saveFile.exists()){
					GeneratorUtils.generator(saveXmlMapperPath, mapperXmlFileName, mapperXmlTemplate, configContext, false);
				}else{
					//存在此文件就进行替换
					String saveXmlStr = IOUtil.toString(new FileInputStream(saveFile), "utf-8");
					indexS = saveXmlStr.indexOf(">",saveXmlStr.indexOf("<resultMap"))+1;
					String beforeXml = saveXmlStr.substring(0,indexS);
					String afterXml = saveXmlStr.substring(saveXmlStr.indexOf("</resultMap>",indexS));
					String completeXml = beforeXml+"\r\n"+resultMapElements+"\r\n"+afterXml;
					IOUtil.copy(new ByteArrayInputStream(completeXml.getBytes("UTF-8")), new FileOutputStream(saveFile));
				}

			} catch (FileNotFoundException e) {
				throw new RuntimeException(e);
			} catch (IOException e) {
				throw new RuntimeException(e);
			}
			deleteFile.delete();
		}


	}


	/**
	 * @description: 生成service和serviceImpl
	 * @param:  basicPath 项目的绝对路径(精确到: 项目/src/main/java/)
	 * @param:  basicPackageName 基础的包名
	 * @param:  modelClassName 对应model的class
	 * @param:  basicServiceClass service需要继承的基础接口
	 * @param:  basicServiceImplClass serviceImpl需要继承的基础类
	 * @return: void
	 * @author: hcl
	 * @date: created in 2018/1/19 9:19
	 */
	public static void generatorServiceCode(String basicPath,
											String basicPackageName,
											String modelClassName,
											String basicServiceClass,
											String basicServiceImplClass){
		basicPath = GeneratorUtils.addPathLine(basicPath);
		String modelName = GeneratorUtils.getSimpleClassName(modelClassName);
		String servicePackage = basicPackageName+".service";

		String servicePackagePath = basicPath + servicePackage.replaceAll("\\.", "/");
		servicePackagePath = GeneratorUtils.addPathLine(servicePackagePath);

		//根据配置文件生成Service
		String serviceName = modelName+"Service";

		VelocityContext context = new VelocityContext();
		context.put("modelClassName",modelClassName);
		context.put("modelName",modelName);
		context.put("servicePackage",servicePackage);
		context.put("serviceName",serviceName);
		context.put("basicServiceClass",basicServiceClass);
		context.put("basicServiceName",GeneratorUtils.getSimpleClassName(basicServiceClass));
		String serviceTemplate = GeneratorUtils.getTemplate("Service.vm");
		GeneratorUtils.generator(servicePackagePath, serviceName+".java", serviceTemplate, context, false);


		//根据配置文件生成ServiceImpl
		String serviceImplPackage = servicePackage+".impl";
		String serviceImplName = serviceName+"Impl";
		String serviceImplPackagePath = servicePackagePath +"/impl";
		serviceImplPackagePath = GeneratorUtils.addPathLine(serviceImplPackagePath);
		String serviceImplTemplate = GeneratorUtils.getTemplate("ServiceImpl.vm");

		context.put("serviceImplPackage",serviceImplPackage);
		context.put("serviceImplName",serviceImplName);
		context.put("basicServiceImplClass",basicServiceImplClass);
		context.put("basicServiceImplName",GeneratorUtils.getSimpleClassName(basicServiceImplClass));
		GeneratorUtils.generator(serviceImplPackagePath, serviceImplName+".java", serviceImplTemplate, context, false);
	}

	
}
